const vscode = require("vscode");
const { colors } = require("./webview/colors/colors");


class ColorBlockDecorationItem {
    /**
     * 
     * @param {RegExp} groupRegex 
     * @param {RegExp} itemRegex 
     */
    constructor(groupRegex, itemRegex) {
        this.groupRegex = groupRegex;
        this.itemRegex = itemRegex;
        this.decorationType = vscode.window.createTextEditorDecorationType({
            before: {
                contentText: " ",
                width: "10x",
                height: "10x",
                margin: "0 2px 0 0",
            },
            rangeBehavior: vscode.DecorationRangeBehavior.ClosedClosed,
        })
    }

    /**
     * @param {vscode.TextEditor} editor 
     * @returns 
     */
    render(editor) {
        const text = editor.document.getText();
        if (!text) {
            return
        }
        const colorRanges = this.findGroup(text).map(item => {
            const startPos = editor.document.positionAt(item.index);
            // 色块装饰器
            return {
                range: new vscode.Range(startPos, startPos),
                renderOptions: {
                    before: {
                        contentText: "■",
                        color: item.color.hex,
                    },
                },
            };
        })
        editor.setDecorations(this.decorationType, colorRanges);
    }

    findGroup(text) {
        let result;
        const list = []
        while ((result = this.groupRegex.exec(text)) !== null) {
            list.push(...this.findItems(result))
        }
        return list;
    }

    /**
     * 
     * @param {RegExpExecArray} execArray 
     */
    findItems(execArray) {
        const text = execArray[0]
        let result;
        const list = []
        while ((result = this.itemRegex.exec(text)) !== null) {
            const color = colors.find((color) => color.number == result[0]);
            list.push({ index: execArray.index + result.index, color })
        }
        return list;
    }
}


const colorBlockDecorationList = [
    new ColorBlockDecorationItem(/autocolor=\d+(,\d+)*/gi, /\d+/g),
    new ColorBlockDecorationItem(/scolor=\d+/gi, /\d+/g),
]


class ColorBlockDecoration {
    constructor(context) {
        this.context = context;
        this.activeEditor = vscode.window.activeTextEditor;
        if (this.activeEditor) {
            this.updateDecorations(this.activeEditor);
        }
    }
    /**
     * 
     * @param {vscode.TextEditor | undefined} editor 
     */
    onDidChangeActiveTextEditor(editor) {
        this.activeEditor = editor;
        if (editor) {
            this.updateDecorations(editor);
        }
    }
    /**
     * 
     * @param {vscode.TextDocumentChangeEvent} event 
     */
    onDidChangeTextDocument(event) {
        if (this.activeEditor && event.document === this.activeEditor.document) {
            this.updateDecorations(this.activeEditor);
        }
    }
    /**
     * 
     * @param {vscode.TextEditor} editor 
     * @returns 
     */
    updateDecorations(editor) {
        colorBlockDecorationList.forEach(item => item.render(editor));
    }

    /**
     * 
     * @param {vscode.ExtensionContext} context 
     */
    static init(context) {
        const decoration = new ColorBlockDecoration(context);
        context.subscriptions.push(
            vscode.window.onDidChangeActiveTextEditor((...args) => decoration.onDidChangeActiveTextEditor.apply(decoration, args)),
            vscode.workspace.onDidChangeTextDocument((...args) => decoration.onDidChangeTextDocument.apply(decoration, args))
        );
    }
}

module.exports = { ColorBlockDecoration };